package cn.com.callback

import cn.com.elite.EliteBean
import cn.com.elite.Util
import cn.com.kh.hst.ThreeDesUtil
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.apache.http.Header
import org.apache.http.HttpEntity
import org.apache.http.client.methods.CloseableHttpResponse
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClientBuilder
import org.apache.http.util.EntityUtils
import org.json.JSONObject

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 *
 * @Title: apiSyncDemo
 * @Description:系统API接口-- 微软邮箱 通过code获取认证token
 * @author: chieh
 * @date 2024-02-01 18:00:55
 *
 */

public class apiSync implements ServiceBackInvoke {
    private static final Log log = LogFactory.getLog(apiSync.class);
    private String apiURL = "http://127.0.0.1:8080/EliteGeneralHttpTask/GeneralService/apiEsopChatOauth";
    private String errorURL = "http://47.113.26.123:8080/webchat";
    private String visitorURL = "http://47.113.26.123:8080/webchat/ghbtest.html";

    public String doCallBack(EliteBean eliteBean, HttpServletRequest request, HttpServletResponse response) {

        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=UTF-8");
        long startTime = System.currentTimeMillis();

        String callBody = "";
        JSONObject outData = new JSONObject();
        outData.put("code", 1);
        outData.put("message", "获取token操作成功");

        String getMethod = request.getMethod();
        log.debug("apiMiniPControl getMethod:" + getMethod);

        // 获取所有Header
        Map<String, String> mapHeader = new HashMap<String, String>();
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            log.debug("apiMiniPControl Header-" + key + ":" + value);

            mapHeader.put(key, value);
        }

        // 获取所有参数名
        Map<String, String> mapParams = new HashMap<String, String>();
        Enumeration ep = request.getParameterNames();
        while (ep.hasMoreElements()) {
            String key = (String) ep.nextElement();
            String value = request.getParameter(key);
            log.debug("apiMiniPControl Parameter-" + key + ":" + value);
            mapParams.put(key, value);

        }
        log.debug("***原始GET请求参数:" + mapParams.toString());

        // 通过state前缀判断是否是网聊OAuth2.0
        if (mapParams.containsKey("state") && mapParams.get("state").startsWith("CHAT")) {
            // TODO 网聊OAuth2.0认证


            // 获取token
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            CloseableHttpResponse callResp = null;
            log.debug("要转发的地址：" + apiURL);
            try {
                // 拼接参数
                mapParams.put("type", "2");
                String queryStr = getQueryString(mapParams);

                // 调用内部接口
                callResp = httpClient.execute(new HttpGet(apiURL + "?" + queryStr));
                HttpEntity entity = callResp.getEntity();
                int status = callResp.getStatusLine().getStatusCode();
                response.setStatus(status);
                if (status == 200 && entity != null) {

                    // 获取响应头
                    Header[] headers = callResp.getAllHeaders();

                    // 获取接口返回
                    String result = EntityUtils.toString(entity, "UTF-8");

                    if (isNull(result) || !result.startsWith("http")) {
                        log.warn("接口返回重定向地址为空：" + result);
                        errorRedirect(response, "地址异常", "接口返回重定向地址错误：" + result);
                    } else {
                        response.sendRedirect(result);
                    }
                } else {
                    errorRedirect(response, "登录处理异常", "登录处理异常错误:无重定向URL");
                }
            } catch (Exception e) {
                log.error("处理异常", e);
            } finally {
                try {
                    if (httpClient != null) {
                        httpClient.close();
                    }
                    if (callResp != null) {
                        callResp.close();
                    }
                } catch (IOException e) {
                    log.error("关闭流异常", e);
                }
            }

            log.debug("网聊OAuth2.0认证Code返回:" + mapParams.toString());
            return mapParams.toString();

        } else {
            // TODO 微软邮箱OAuth2.0认证
            String code = "";
            String hst_guid = "";
            code = mapParams.get("code");
            hst_guid = mapParams.get("state");
            log.debug("***code:" + code + "***hsc_guid:" + hst_guid);

            //策略待补充，目前固定走 chieh1@dev-cc.kuangheng.com
            //hsc_guid="E0069D01-794C-11EE-B1F7-00163E145047";
            /*
            String client_id="d005a907-a74c-43e7-abfa-353198939190";
            String client_secret="HyC8Q~VYik7X-r5-59ktb-yUoVaFuTCbY5mnuaZp";
            String tenan_ID="62508139-839f-43ea-b21f-2da650c20e46";
            String redirect_uri="https://dev-cc.kuangheng.com/ngsapitask_ph/api/apiSync";
             */

            String client_id = "";
            String client_secret = "";
            String tenan_ID = "";
            String redirect_uri = "";
            String grant_type = "authorization_code";
            String scope = "https://graph.microsoft.com/.default";
            String token_url = "";

            try {

                def getSelectSQL = eliteBean.chaxun_sql("select b.tenan_ID,b.client_id,b.client_secret,b.redirect_uri,b.token_url from hst_email_config a LEFT JOIN hst_email_parameter b on a.ipserver=b.hst_guid where 1=1 and a.hst_guid='" + hst_guid + "' order by  b.updateDate desc limit 1", "dataSource");
                log.debug("SQL获取数据:" + getSelectSQL);
                if (getSelectSQL.size() > 0) {
                    client_id = getSelectSQL.get(0).get("client_id");
                    client_secret = getSelectSQL.get(0).get("client_secret");
                    tenan_ID = getSelectSQL.get(0).get("tenan_ID");
                    redirect_uri = getSelectSQL.get(0).get("redirect_uri");
                    token_url = getSelectSQL.get(0).get("token_url");

                    log.debug("client_id:" + client_id + "client_secret:" + client_secret + "tenan_ID:" + tenan_ID + "redirect_uri:" + redirect_uri + "token_url:" + token_url);
                }

                String doURL = token_url.replace("{tenant_id}", tenan_ID);
                log.debug("doURL:" + doURL);

                HashMap<String, String> paramHashMap = new HashMap<String, String>() {
                    {
                        put("client_id", client_id);
                        put("scope", URLEncoder.encode(scope));
                        put("redirect_uri", URLEncoder.encode(redirect_uri));
                        put("grant_type", grant_type);
                        put("client_secret", client_secret);
                        put("code", code);
                    }
                };

                String injson = ThreeDesUtil.SplicingMap(paramHashMap, "&");
                log.debug("injson:" + injson);

                Map<String, String> headMap = new HashMap<String, String>();
                headMap.put("Content-Type", "application/x-www-form-urlencoded");
                def getResult = Util.doHttpPostUseHead(doURL, injson, "UTF-8", 10000, 0, headMap);
                log.debug("返回的参数getResult:" + getResult);

                //解析SSO返回信息
                JSONObject jsonObject = new JSONObject(getResult);
                String error_codes = GetJV(jsonObject, "error_codes");
                String access_token = GetJV(jsonObject, "access_token");
                String refresh_token = GetJV(jsonObject, "refresh_token");
                String expires_in = GetJV(jsonObject, "expires_in");//考虑到 首次token的认证不生效，则默认为0 由刷新token处理获取新的token
                log.debug("error_codes:" + error_codes);
                log.debug("access_token:" + access_token);
                log.debug("refresh_token:" + refresh_token);
                log.debug("expires_in:" + expires_in);

                if (error_codes == "") {
                    //返回认证信息成功
                    def updatetoken = eliteBean.update("update hst_email_config set refresh_token='" + refresh_token + "',access_token='" + access_token + "',expires_in='0',expires_Date=now() where  hst_guid='" + hst_guid + "'", "dataSource");
                    log.debug("updatetoken:" + updatetoken);
                    outData.put("access_token", access_token);
                } else {
                    outData.put("code", -1);
                    outData.put("message", "HTTP请求调用类型错误，接口调用失败：" + getResult);
                    log.error(outData);
                    return outData.toString();
                }
            } catch (Exception e) {
                log.error("接口处理异常" + e.getMessage());
                outData.put("code", -1);
                outData.put("message", "HTTP请求调用类型错误，接口调用失败：" + getMethod);
                log.error(outData);
                return outData.toString();
            }

            log.debug("Esop获取token令牌apiSync返回:" + outData.toString());
            return outData.toString();
        }

    }

    // 解析Json值
    public static String GetJV(JSONObject inJson, String getKey) {
        String Rev_Value = null;
        try {
            Rev_Value = inJson.getString(getKey);
        } catch (Exception e) {
            try {
                Rev_Value = String.valueOf(inJson.getInt(getKey));
            } catch (Exception e1) {
                try {
                    Rev_Value = String.valueOf(inJson.getJSONArray(getKey));
                } catch (Exception e2) {
                    try {
                        Rev_Value = String.valueOf(inJson.getJSONObject(getKey));
                    } catch (Exception e3) {
                        Rev_Value = "";
                    }
                }
            }
        } finally {
            if (Rev_Value == null || Rev_Value.equals("null") || Rev_Value.length() <= 0) {
                Rev_Value = "";
            } else {
            }
        }
        log.debug("解析-k=" + getKey + " v=" + Rev_Value);
        return Rev_Value;
    }


    // 异常&错误重定向
    public void errorRedirect(HttpServletResponse response, String ErrorTitle, String ErrorInfo) throws IOException {
        log.warn("异常&错误[apiDynLogin]重定向 ErrorTitle:" + ErrorTitle + " ErrorInfo:" + ErrorInfo);
        ErrorTitle = isNull(ErrorTitle) ? "页面异常" : ErrorTitle;
        ErrorInfo = isNull(ErrorInfo) ? "请稍后再试或联系管理员." : ErrorInfo;
        response.sendRedirect(this.errorURL + "/404.html?ErrorTitle=" + encode(ErrorTitle) + "&ErrorInfo=" + encode("登录异常&错误:" + ErrorInfo).replaceAll("\\+", "%20"));
    }

    // 工具方法
    public static String getQueryString(Map<String, String> params) {
        String url = "";
        if (params == null) {
            return url;
        }

        StringBuilder builder = new StringBuilder(url);

        int i = 0;
        for (String key : params.keySet()) {
            String value = params.get(key);
            if (value == null) { // 过滤空的key
                continue;
            }

            if (i != 0) {
                builder.append('&');
            }

            builder.append(key);
            builder.append('=');
            builder.append(encode(value));

            i++;
        }

        return builder.toString();
    }

    // 工具方法
    public static String encode(String input) {
        if (input == null) {
            return "";
        }

        try {
            return URLEncoder.encode(input, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return input;
    }

    // 解析Mapn值(此方法增加需要解析的key不存在保护)
    public static String GetMapV(Map inMap, String getKey) {
        String Rev_Value = null;
        try {
            Rev_Value = String.valueOf(inMap.get(getKey));
        } catch (Exception e) {

            Rev_Value = "";
        } finally {
            if (Rev_Value == null || Rev_Value.equals("null") || Rev_Value.length() <= 0) {
                Rev_Value = "";
            }
        }
        return Rev_Value;
    }

    // 非空校验isNull
    public static boolean isNull(String value) {

        boolean reFlag = true;
        if (value == null || value.length() <= 0) {
            reFlag = true;
        } else {
            reFlag = false;
        }

        return reFlag;
    }
}